<?
// *****************************************************************************
// Модуль новостей
// Префикс news_
// Версия от 24.08.2006
// Автор: Алексей Дьяченко
// Библиотека распространяется по лицензии GPL
// Принять участие в разработке или скачать новую версию вы можете на сайте
// http://www.my-site.ru/
/*
	Copyright 2006 Alex Djachenko http://www.my-site.ru
	Authors: Alex Djachenko
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
// *****************************************************************************

/*
Файл инициализации модуля.
Этот файл является обязательным для любого модуля.
Содержит подключение необходимых модулей, инициализациюпеременных,
объявления функций и классов.
*/

// Инициализируем библиотеку отправки email
mst_initlib('eml');
// Инициализируем модуль sharpobj: нам нужна версия, не младше 20060825
mst_initmod('sharpobj',20060908);
// Инициализируем модуль onedit
mst_initmod('onedit');
// Загружаем сигму, передав путь к сигме загрузчику модуля pear
mst_modload('pear','HTML/Template/Sigma');
// Загружаем сигму
mst_modload('pear','HTML/QuickForm');

// Перечисляем переменные из $MT_mod_dat, 
// которые нужно регистрировать в окружении при запуске файла модуля.
// Окружение автоматически устанавливается при загрузке файла
// через mst_modfileload()
$MT_mod_envvars='Processor';

// Дальше объявлем классы и функции модуля,
// их имена должны содержать префикс из имени модуля.


// Данные о запрашиваемой конференции
// Наследуем класс объекта-контейнера из модуля shrapobj
// и переопределяем конструктор, чтоб добавить
// нужные нам поля.
// Объекты этого класса используются для передачи 
// параметры выборки сообщений классу-процессору
class news_shdata_qmsg extends sharpobj_data_item_data
{
    function __construct($options=null)
    {
		// Вызываем конструктор объекта-родителя
        parent::__construct($options);
		// ID конференции
		$this->addItem('confid','int');
		// Количество сообщений
		$this->addItem('maxmsg','int');
		// Начальное сообщение
		$this->addItem('begin','int');
    }
}

// Процессор
// Наследуем класс-процессор из модуля sharpobj
// в котором агрегируем бизнес-логику нашего приложения
// (Если бы приложение было более сложным и работало 
// со сложными базами данных, осночные SQL-запросы,
// не требующие работы сразу с несколькими таблицами,
// мы бы вынесли в объект-хранилище)
// Снаружи к классу-процессору мы должны обращаться
// с помощью метода action(), который проверят
// корректность типов передаваемых аргументов и
// транслирует запрос в вызов метода act_
// Мы можем так же объявлять методы pvt_,
// никаких ограничений на типы и количество аргументов
// которых не накладывается, но обращаться к ним можно
// только изнутри класса-процессора.
// Эти правила помогут акуратно агрегировать данные в классе-процессоре 
class news_processor extends sharpobj_processor
{
	function __construct()
	{
		// Создаем справочники
		// Задаем формат справочника Базы сообщений
		$format_msg = new sharpobj_storage_format();
		$format_msg->addItem('confid','confid','int');
		$format_msg->addItem('date_send','date_send','int');
		$format_msg->addItem('date_actual','date_actual','int');
		$format_msg->addItem('sabj','sabj','row');
		$format_msg->addItem('url','url','url');
		$format_msg->addItem('img','img','url');
		$format_msg->addItem('text','text','text');
		$format_msg->addItem('ip','ip','row');
		$format_msg->addItem('del','del','smallatword');
		$format_msg->addItem('type','type','smallatword');
		$format_msg->addItem('full_text','full_text','html');

		// Объявляем справочник
		$DB_msg = new sharpobj_storage_simplemysql($format_msg,
			array('tbname'=>'news_msg','idfield'=>'id'));
		// Добавляем справочник к процессору
		$this->storageAdd('msg',$DB_msg);

	}

	/**
	 * 	Получить ленту сообщений из базы данных	
	 * @param news_shdata_qmsg	$dataobj
	 * @return unknown
	 */
    function act_getmsg(news_shdata_qmsg $dataobj)
    {
		
		$sql = "SELECT #!id# FROM #!table# WHERE "
			." confid='{$dataobj->get('sql','confid')}'"
			." AND del='false'"
			." ORDER by date_actual DESC"
			." LIMIT {$dataobj->get('sql','begin')},{$dataobj->get('sql','maxmsg')}";
		
		$result = $this->storageLink('msg')->sqlqueryList($sql);
		
		
		
		return $result;
    }
	/**
	 * Посчитать количество сообщений в ленте	
	 * @param news_shdata_qmsg	$dataobj
	 * @return number
	 */
    function act_countmsg(news_shdata_qmsg $dataobj)
    {
		
		$sql = "SELECT COUNT(*) FROM #!table# WHERE "
			." confid='{$dataobj->get('sql','confid')}'"
			." AND del='false';";
		
		$result = $this->storageLink('msg')->sqlqueryOneValue($sql);
		
		
		
		return (int)$result;
    }
	/**
	 * Посчитать количество страниц в ленте
	 * (вообще, надо бы написать отдельную библиотеку для этих подсчетов
	 * - слишком часто они нужны, а то что есть в mst_ppagesurl()
	 * был ошибкой с самого начала)	
	 * @param news_shdata_qmsg	$dataobj
	 * @return number
	 */
    function act_countpages(news_shdata_qmsg $dataobj)
    {
		
		$count_msg = $this->act_countmsg($dataobj);
		$pages = (int) round($count_msg/$dataobj->get('sql','maxmsg'))+1;	
		return $pages;
    }
	/**
	 * Получить одну новость из базы	
	 * @param $dataobj
	 * @return unknown
	 */
    function act_getnews($dataobj)
    {
		return $this->storageLink('msg')->get($dataobj);
    }
	/**
	 * Добавить новость в базу	
	 * @param $dataobj
	 * @return unknown
	 */
    function act_addnews($dataobj)
    {
		return $this->storageLink('msg')->insert($dataobj);
    }
	/**
	 * Помечаем новость как удаленную	
	 * @param $dataobj
	 * @return unknown
	 */
    function act_delnews($dataobj)
    {
		// Получаем объект новости из базы
		$msg = $this->storageLink('msg')->get($dataobj);
		if (!$msg)
		{
			return false;
		}
		// Изменяем статус новости
		$msg->set('plain','true','del');
		// Записываем объект обратно в базу
		return $this->storageLink('msg')->update($msg);
    }
}

// Функция отрисовки ленты новостей
function news_show($confid,$maxmsg,$page,$lenta_tml,&$Switcher)
{
	$ppath = mst_modpath_parsethis();
	$MT_mod_name = $ppath['MT_mod_name'];
	// Получаем ссылку на процессор
	$Processor = mst_getdatemod($MT_mod_name,'Processor');
	// Инициализируем шаблонный движок Sigma из пакета PEAR
	$tml = new HTML_Template_Sigma('/');
	// Загружаем шаблон ленты новостей
	$tml->loadTemplateFile(mst_modpath($MT_mod_name,$lenta_tml));
	// Регистрируем функцию date() в качестве функции шаблона
	// для большей гибкости в форматировании даты.
	$tml->setCallbackFunction('date', 'date');
	// Создаем объект с параметрами запроса
	$qmsg = new news_shdata_qmsg();
	// Задаем параметры вывода ленты
	$qmsg->set('plain',array('confid'=>$confid,'maxmsg'=>$maxmsg,'begin'=>0));
	// Запрашиваем количество новостей
	// (здесь мы обращаемся к методу act_countpages(), который
	// объявили в init.php)
	// $countpages = $Processor->action('countpages',$qmsg);
    $countpages = $Processor->countpages($qmsg);
	// Вычисление начального сообщения
	// $page = $Switcher->next();
	if ($page>0 AND $page!=$countpages)
	{
		// Передан номер страницы
		// Считаем смещение текущей страницы
		$begin = ($countpages-$page)*$qmsg->get('plain','maxmsg');
		$qmsg->set('plain',$begin,'begin');
		// Выводим ссылку для возврата на начальную страницу
		$tml->setVariable('page_name',0);
		// PREV является ключевым словом, обозначающим предыдущий
		// уровень (текщий уровень увеличивается по мере вызова
		// метода next())
		$tml->setVariable('page_url',$Switcher->url('PREV'));
		$tml->parse('pages');
		// echo $page.' '.$qmsg->get('plain','begin');
	}
	// Здесь мы рисуем указатель страниц, если все сообщения не умаются на одной
	// (надо бы сделать модуль для этого)
	if ($countpages>1)
	{
		for($page=($countpages-1);$page>0;--$page)
		{
			//
			$tml->setVariable('page_name',$countpages-$page);
			$tml->setVariable('page_url',$Switcher->url('PREV/'.$page));
			$tml->parse('pages');
		}
	}
	// Дальше выводим сообщения в ленту новостей
	// Запрашиваем список сообщений
	// $msglist = $Processor->action('getmsg',$qmsg);
    $msglist = $Processor->getmsg($qmsg);
	foreach ($msglist as $msg)
	{
		// Устанавливаем данные новости
		if (onedit_check())
		{
			// Включен режим редактирования
			$tml->setVariable('tools','<a href="'.$Switcher->url('delnews/'.$msg->getId()).'">Удалить</a>');
		}
		$tml->setVariable($msg->get('html'));
		$tml->setVariable('id',$msg->getId());
		// Проверяем тип ссылки в новости (текст или ссылка)
		if ($msg->get('plain','type')=='url')
		{
			if (!$msg->isNoData('url'))
			{
				// В новости есть ссылка
				$tml->setVariable('link',"<a href=\"{$msg->get('plain','url')}\">Подробнее...</a>");
			}
		}else
		{
			if (!$msg->isNoData('full_text'))
			{
				// В новости есть текст
				$tml->setVariable('link',"<a href=\"".$Switcher->url('PREV/text/'.$msg->getId())."\">Подробнее...</a>");
			}
		}
		if (!$msg->isNoData('img'))
		{
			// В новости есть картинка
			$tml->setVariable('pict',"<img src=\"{$msg->get('plain','img')}\"/>");
		}
		$tml->parse('news');
	
	}
	// Обрабатываем остальной шаблон
	$tml->parse();
	// Показываем шаблон
	$tml->show();
}


//  Обьявляем данные модуля
// Объявляем объект-конструктор и кладем его в массив $MT_mod_dat,
// откуда он автоматически попадет в массив данных модуля
// и будет доступен в окружении модуля.
// (поскольку мы перечислили переменную в $MT_mod_envvars,
// она еще автоматически будет распаковываться из массива
// MT_mod_dat в окружение модуля).
$MT_mod_dat['Processor'] = new news_processor(); 

?>
